package com.example.performance.service;

import com.example.performance.config.ConfigLoader;
import com.example.performance.model.LoadTestConfig;
import com.example.performance.model.TestScenario;
import com.example.performance.model.HttpRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 场景管理服务
 * 负责场景配置的CRUD操作和文件管理
 */
@Service
public class ScenarioManagementService {

    private static final Logger logger = LoggerFactory.getLogger(ScenarioManagementService.class);

    private final ConfigLoader configLoader;
    private final String configDirectory = "web-configs";
    private final Map<String, LoadTestConfig> configCache = new HashMap<String, LoadTestConfig>();

    public ScenarioManagementService() {
        this.configLoader = new ConfigLoader();
        initializeConfigDirectory();
    }

    /**
     * 初始化配置文件目录
     */
    private void initializeConfigDirectory() {
        File dir = new File(configDirectory);
        if (!dir.exists()) {
            if (dir.mkdirs()) {
                logger.info("创建配置文件目录: {}", configDirectory);
            } else {
                logger.error("无法创建配置文件目录: {}", configDirectory);
            }
        }
    }

    /**
     * 获取所有配置的摘要信息
     * 
     * @return 配置摘要列表
     */
    public List<ConfigSummary> getAllConfigSummaries() {
        List<ConfigSummary> summaries = new ArrayList<ConfigSummary>();

        File dir = new File(configDirectory);
        File[] files = dir.listFiles(
                (file, name) -> name.toLowerCase().endsWith(".yml") || name.toLowerCase().endsWith(".yaml") ||
                        name.toLowerCase().endsWith(".json"));

        if (files != null) {
            for (File file : files) {
                try {
                    LoadTestConfig config = configLoader.loadFromFile(file.getAbsolutePath());
                    ConfigSummary summary = new ConfigSummary();
                    summary.setId(getConfigId(file.getName()));
                    summary.setFileName(file.getName());
                    summary.setTestName(config.getTestName());
                    summary.setDescription(config.getDescription());
                    summary.setConcurrentUsers(config.getConcurrentUsers());
                    summary.setTestDurationSeconds(config.getTestDurationSeconds());
                    summary.setScenarioCount(config.getScenarios().size());
                    summary.setLastModified(file.lastModified());
                    summaries.add(summary);
                } catch (Exception e) {
                    logger.error("加载配置文件失败: {}", file.getName(), e);
                }
            }
        }

        return summaries;
    }

    /**
     * 根据ID获取配置
     * 
     * @param configId 配置ID
     * @return 配置对象
     */
    public LoadTestConfig getConfigById(String configId) throws IOException {
        if (configCache.containsKey(configId)) {
            return configCache.get(configId);
        }

        String fileName = getFileNameFromId(configId);
        String filePath = configDirectory + File.separator + fileName;

        LoadTestConfig config = configLoader.loadFromFile(filePath);
        configCache.put(configId, config);
        return config;
    }

    /**
     * 保存配置
     * 
     * @param config   配置对象
     * @param configId 配置ID（可选）
     * @return 配置ID
     */
    public String saveConfig(LoadTestConfig config, String configId) throws IOException {
        if (configId == null || configId.isEmpty()) {
            configId = generateConfigId();
        }

        String fileName = getFileNameFromId(configId) + ".yml";
        String filePath = configDirectory + File.separator + fileName;

        configLoader.saveToFile(config, filePath);
        configCache.put(configId, config);

        logger.info("保存配置: {} -> {}", config.getTestName(), filePath);
        return configId;
    }

    /**
     * 删除配置
     * 
     * @param configId 配置ID
     */
    public boolean deleteConfig(String configId) {
        try {
            String fileName = getFileNameFromId(configId);
            String filePath = configDirectory + File.separator + fileName;

            File file = new File(filePath);
            if (file.exists()) {
                boolean deleted = file.delete();
                if (deleted) {
                    configCache.remove(configId);
                    logger.info("删除配置文件: {}", filePath);
                    return true;
                }
            }
            return false;
        } catch (Exception e) {
            logger.error("删除配置失败: {}", configId, e);
            return false;
        }
    }

    /**
     * 创建新的空配置
     * 
     * @return 新配置对象
     */
    public LoadTestConfig createNewConfig() {
        LoadTestConfig config = new LoadTestConfig();
        config.setTestName("新建性能测试");
        config.setDescription("请配置测试描述");
        config.setConcurrentUsers(10);
        config.setTestDurationSeconds(60);
        config.setRampUpSeconds(5);

        // 添加默认场景
        TestScenario defaultScenario = new TestScenario("默认测试场景", "默认的HTTP请求测试场景");
        HttpRequest defaultRequest = new HttpRequest("示例请求", "GET", "https://httpbin.org/json");
        defaultScenario.addRequest(defaultRequest);
        config.addScenario(defaultScenario);

        return config;
    }

    /**
     * 验证配置
     * 
     * @param config 配置对象
     * @return 验证结果
     */
    public ValidationResult validateConfig(LoadTestConfig config) {
        ValidationResult result = new ValidationResult();
        result.setValid(true);
        List<String> errors = new ArrayList<String>();

        if (config.getTestName() == null || config.getTestName().trim().isEmpty()) {
            errors.add("测试名称不能为空");
        }

        if (config.getConcurrentUsers() <= 0) {
            errors.add("并发用户数必须大于0");
        }

        if (config.getTestDurationSeconds() <= 0) {
            errors.add("测试持续时间必须大于0");
        }

        if (config.getScenarios().isEmpty()) {
            errors.add("至少需要配置一个测试场景");
        }

        for (TestScenario scenario : config.getScenarios()) {
            if (scenario.getRequests().isEmpty()) {
                errors.add("场景 '" + scenario.getName() + "' 至少需要配置一个HTTP请求");
            }

            for (HttpRequest request : scenario.getRequests()) {
                if (request.getUrl() == null || request.getUrl().trim().isEmpty()) {
                    errors.add("场景 '" + scenario.getName() + "' 中存在空的请求URL");
                }
            }
        }

        result.setErrors(errors);
        result.setValid(errors.isEmpty());

        return result;
    }

    /**
     * 生成配置ID
     */
    private String generateConfigId() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 从文件名获取配置ID
     */
    private String getConfigId(String fileName) {
        int lastDot = fileName.lastIndexOf('.');
        return lastDot > 0 ? fileName.substring(0, lastDot) : fileName;
    }

    /**
     * 从配置ID获取文件名
     */
    private String getFileNameFromId(String configId) {
        File dir = new File(configDirectory);
        File[] files = dir.listFiles((file, name) -> name.startsWith(configId + "."));

        if (files != null && files.length > 0) {
            return files[0].getName();
        }

        return configId; // 如果找不到，返回ID本身
    }

    /**
     * 配置摘要信息
     */
    public static class ConfigSummary {
        private String id;
        private String fileName;
        private String testName;
        private String description;
        private int concurrentUsers;
        private int testDurationSeconds;
        private int scenarioCount;
        private long lastModified;

        // Getter和Setter方法
        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getFileName() {
            return fileName;
        }

        public void setFileName(String fileName) {
            this.fileName = fileName;
        }

        public String getTestName() {
            return testName;
        }

        public void setTestName(String testName) {
            this.testName = testName;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public int getConcurrentUsers() {
            return concurrentUsers;
        }

        public void setConcurrentUsers(int concurrentUsers) {
            this.concurrentUsers = concurrentUsers;
        }

        public int getTestDurationSeconds() {
            return testDurationSeconds;
        }

        public void setTestDurationSeconds(int testDurationSeconds) {
            this.testDurationSeconds = testDurationSeconds;
        }

        public int getScenarioCount() {
            return scenarioCount;
        }

        public void setScenarioCount(int scenarioCount) {
            this.scenarioCount = scenarioCount;
        }

        public long getLastModified() {
            return lastModified;
        }

        public void setLastModified(long lastModified) {
            this.lastModified = lastModified;
        }
    }

    /**
     * 验证结果
     */
    public static class ValidationResult {
        private boolean valid;
        private List<String> errors;

        public ValidationResult() {
            this.errors = new ArrayList<String>();
        }

        public boolean isValid() {
            return valid;
        }

        public void setValid(boolean valid) {
            this.valid = valid;
        }

        public List<String> getErrors() {
            return errors;
        }

        public void setErrors(List<String> errors) {
            this.errors = errors;
        }
    }
}